
from datetime import date
from django.shortcuts import render
from django.db.models import F, Q
from django.core.cache import cache
from django.shortcuts import get_object_or_404
from django.views.generic import ListView, DetailView
from django_redis import get_redis_connection

from elasticsearch import Elasticsearch
from haystack.views import SearchView as _SearchView

from blog.models import (Category, Tag, Article)
from config.models import (Link, )
from comment.forms import CommentForm
from comment.models import Comment

PAGE_SIZE = 15


class CommonViewMixin:
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update(Category.get_navs())
        context.update(Tag.get_all_tags())
        return context


class IndexView(CommonViewMixin, ListView):
    queryset = Article.objects.filter(status=Article.STATUS_NORMAL).select_related('category')
    paginate_by = PAGE_SIZE
    context_object_name = 'article_list'
    template_name = 'blog/list.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        conn = get_redis_connection('default')
        history_key = 'history_python'
        article_ids = conn.lrange(history_key, 0, 4)
        if article_ids:
            sku_article_res = []
            for article_id in article_ids:
                article = Article.objects.filter(status=Article.STATUS_NORMAL, pk=int(article_id))
                if article:
                    sku_article_res.append(article[0])
            context.update({
                'sku_articles': sku_article_res
            })
        return context


class CategoryView(IndexView):
    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        category_id = self.kwargs.get('category_id')
        category = get_object_or_404(Category, pk=category_id)
        context.update({
            'category': category,
        })
        return context

    def get_queryset(self):
        queryset = super().get_queryset()
        category_id = self.kwargs.get('category_id')
        return queryset.filter(category_id=category_id)


class TagView(IndexView):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        tag_id = self.kwargs.get('tag_id')
        tag = get_object_or_404(Tag, pk=tag_id)
        context.update({
            'tag': tag
        })
        return context

    def get_queryset(self):
        queryset = super().get_queryset()
        tag_id = self.kwargs.get('tag_id')
        return queryset.filter(tag_id=tag_id)


class ArticleDetailView(CommonViewMixin, DetailView):
    queryset = Article.objects.filter(status=Article.STATUS_NORMAL)
    template_name = 'blog/detail.html'
    context_object_name = 'article'
    pk_url_kwarg = 'article_id'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({
            'comment_form': CommentForm,
            'comment_list': Comment.get_by_target(self.request.path)
        })
        return context

    def handle_visited(self):
        increase_pv = False
        increase_uv = False
        uid = 'python'  # self.request.uid
        pv_key = 'pv:%s:%s' % (uid, self.request.path)
        uv_key = 'uv:%s:%s:%s' % (uid, str(date.today()), self.request.path)
        if not cache.get(pv_key):
            increase_pv = True
            cache.set(pv_key, 1, 1 * 60)  # 1 分钟有效

        if not cache.get(uv_key):
            increase_uv = True
            cache.set(pv_key, 1, 24 * 60 * 60)  # 24 小时有效
        elif increase_pv:
            Article.objects.filter(pk=self.object.id).update(pv=F('pv') + 1, uv=F('uv') + 1)
        elif increase_uv:
            Article.objects.filter(pk=self.object.id).update(uv=F('uv') + 1)

    def get(self, request, *args, **kwargs):
        response = super().get(request, *args, **kwargs)
        self.handle_visited()
        # from redis import StrictRedis
        # str = StrictRedis(host='', port=6379, db=1)
        conn = get_redis_connection('default')
        history_key = 'history_python'
        # 移除列表中的 article_id
        conn.lrem(history_key, 0, self.object.id)
        # 把article_id插入到列表的左侧
        conn.lpush(history_key, self.object.id)
        # 只保存用户最新浏览的10条信息
        conn.ltrim(history_key, 0, 4)
        return response


class ArticleListView(ListView):
    queryset = Article.latest_articles()
    paginate_by = PAGE_SIZE
    context_object_name = 'article_list'
    template_name = 'blog/list.html'


class SearchView(IndexView):
    template_name = 'search/search.html'

    def get_context_data(self):
        context = super().get_context_data()
        context.update({
            'keyword': self.request.GET.get('keyword', '')
        })
        return context

    def get_queryset(self):
        queryset = super().get_queryset()
        keyword = self.request.GET.get('keyword')
        if not keyword:
            return queryset
        # select * from post where title like '%<keyword>%' or title like '%<keyword>%'
        return queryset.filter(Q(title__icontains=keyword) | Q(desc__icontains=keyword))


class HaystackSearchView(CommonViewMixin, _SearchView):
    pass


class MultiSearchView(IndexView):
    template_name = 'search/search.html'


class ArchiveView(IndexView):
    queryset = Article.get_archive()
    template_name = 'blog/archive.html'
    context_object_name = 'archive_data'

